﻿Imports System.Configuration
Imports System.Reflection

Imports Itvirtuoso.Diagnostics.Profiler.Recorder

Namespace Diagnostics.Profiler
    Public NotInheritable Class ProfilerManager
        Private Shared _recorders As New List(Of BaseRecorder)
        <ThreadStatic()> Private Shared _callStack As Stack(Of MethodCall)
        <ThreadStatic()> Private Shared _currentMethodCall As MethodCall

        Shared Sub New()
            _recorders.Add(New FileRecorder())
        End Sub

        Private Shared Function IsProfilerEnabled() As Boolean
            Dim section As ProfilerSection = CType(ConfigurationManager.GetSection("itvirtuoso/profiler"), ProfilerSection)
            Return Not section Is Nothing AndAlso section.Enabled
        End Function

        Friend Shared Sub EntryMethod(ByVal method As MethodBase)
            If Not IsProfilerEnabled() Then
                Return
            End If

            If _callStack Is Nothing Then
                _callStack = New Stack(Of MethodCall)
            End If

            If Not _currentMethodCall Is Nothing Then
                _callStack.Push(_currentMethodCall)
            End If

            _currentMethodCall = New MethodCall()
        End Sub

        Friend Shared Sub ExitMethod(ByVal method As MethodBase)
            If Not IsProfilerEnabled() Then
                Return
            End If

            _currentMethodCall.ExitMethod()

            Dim parentMethodCall As MethodCall = Nothing
            If _callStack.Count > 0 Then
                parentMethodCall = _callStack.Pop()
                parentMethodCall.AddCallerSpan(_currentMethodCall.CallingFullSpan)
            End If

            Dim key As String = method.DeclaringType.FullName & ":" & method.ToString()
            For Each recorder As BaseRecorder In _recorders
                recorder.Record(key, _currentMethodCall.CallingSpan)
            Next
            _currentMethodCall = parentMethodCall
        End Sub
    End Class
End Namespace
